package ar.edu.utn.frba.tacs.warnes.jms;

import java.util.ArrayList;

import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.Session;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.support.converter.MessageConversionException;
import org.springframework.jms.support.converter.MessageConverter;

import ar.edu.utn.frba.tacs.warnes.Item;
import ar.edu.utn.frba.tacs.warnes.entities.Pedido;
import ar.edu.utn.frba.tacs.warnes.entities.Pieza;
import ar.edu.utn.frba.tacs.warnes.excepciones.JmsTimeOutException;
import ar.edu.utn.frba.tacs.warnes.utils.ContenedorWarnes;

public class ConsumidorJms implements MessageConverter {
	public ConsumidorJms() {
	}

	/**
	 * Convierte un mensaje recibido de la cola en un Pedido de nuestro dominio.
	 * No realiza conversion de objeto a mensaje ya que no realizamos envios a
	 * la cola. Se usa al llamar a receiveAndConvert();
	 */
	public Object fromMessage(Message message) throws JMSException,
			MessageConversionException {

		if (!(message instanceof ObjectMessage)) {
			throw new MessageConversionException(
					"El mensaje no es un ObjectMessage");
		}

		// Casteamos el menssage a ObjectMessage
		ObjectMessage objectMessage = (ObjectMessage) message;

		// Obtenemos el pedido del mensaje que recibimos de la cola
		ar.edu.utn.frba.tacs.warnes.Pedido pedidoApi = (ar.edu.utn.frba.tacs.warnes.Pedido) objectMessage
				.getObject();

		// Creamos un pedido de nuestro dominio
		Pedido pedido = ContenedorWarnes.getInstance().crearUnPedido(
				new ArrayList<Pieza>());

		// Tranformamos los items en piezas y las agregamos al pedido.
		for (Item item : pedidoApi.getItems()) {
			for (int i = 0; i < item.getCantidad(); i++) {
				Pieza pieza = ContenedorWarnes.getInstance().creaUnaPieza();
				if (item.getCodigo() != null && !"".equals(item.getCodigo()))
					pieza.setDescripcion(item.getCodigo());
				if (item.getPrecioUnitario() != null
						&& !"".equals(item.getPrecioUnitario()))
					pieza.setPrecioEnPesos(item.getPrecioUnitario()
							.floatValue());
				pedido.agregarPieza(pieza);
			}
		}
		return pedido;
	}

	/**
	 * No necesitamos implementar el toMessage(), xq no se envia nada a la cola.
	 */
	public Message toMessage(Object object, Session session)
			throws JMSException, MessageConversionException {
		return null;
	}

	public void procesarPedido(Pedido pedido) {
		if (pedido != null) {
			pedido.efectivizar();
			pedido.save();
		}
	}

	public Pedido consumirCola() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"/jms-client-context.xml");
		JmsTemplate a = new JmsTemplate();
		a.setDefaultDestination((Queue) ctx.getBean("requestQueue"));
		a.setConnectionFactory((ConnectionFactory) ctx
				.getBean("connectionFactory"));
		a.setMessageConverter(new ConsumidorJms());
		a.setReceiveTimeout(21000);
		Object obj = a.receiveAndConvert();

		// Si ya se consumieron todos los pedidos de la cola,
		// sale por time out y tira esta exception.
		if (obj == null)
			throw new JmsTimeOutException(
					"Se ha expirado el tiempo de espera ("
							+ a.getReceiveTimeout()
							+ "ms) y ningun pedido fue consumido de la cola.");

		this.procesarPedido((Pedido) obj);
		return (Pedido) obj;
	}
}
